<?php

namespace app\index\controller;

use app\common\JwtHelper;
use app\index\job\JobOrder;
use app\middleware\SecurityMiddleware;
use think\Cache;
use think\Controller;
use think\Db;
use think\Loader;
use think\Queue;
use think\Request;
use think\Validate;
use uploadImg\imgcompress;

class Api extends Controller
{
    public function __construct()
    {
        parent::__construct();

        // 调用中间件
        $middleware = new SecurityMiddleware();
        $request = Request::instance();
        $middleware->handle($request, function ($req) {
            // 仅执行验证，不做中间件链路回调
            return response(); // 返回空响应对象用于中间件添加响应头
        });
    }

    public static function authorizationGetOpenid()
    {
        $request = request(); // 获取当前请求

        $authHeader = $request->header('authorization', '');

        if ($authHeader && stripos($authHeader, 'Bearer ') === 0) {
            $token = substr($authHeader, 7);
            $payload = JwtHelper::verifyToken($token);

            if ($payload && !empty($payload['openid'])) {
                // 可选：自动续期（设置响应头，供中间件读取）
                if (JwtHelper::shouldRefreshToken($payload)) {
                    $newToken = JwtHelper::createToken(['openid' => $payload['openid']]);
                    header('X-Refreshed-Token: ' . $newToken);
                }
            }
        }
        return $payload['openid'] ? : '';
    }

    public function codeGetOpenidToUserInfo()
    {
        $input = Request()->param();

        $code = $input['code'];

        if (empty($code)) apiReturn(2, 'code缺失');

        $appid = C('XCX_APPID');
        $secret = C('XCX_SECRET');
        $grant_type = 'authorization_code';
        $url = 'https://api.weixin.qq.com/sns/jscode2session?';
        $param = [
            'appid' => $appid,
            'secret' => $secret,
            'js_code' => $code,
            'grant_type' => $grant_type
        ];
        $param_str = http_build_query($param);
        $url .= $param_str;
        $user_data = json_decode(file_get_contents($url));

        $openid = $user_data->openid;

        $user_info = Db::name('user')->field('id,username,avatar')->where(['openid' => $openid])->find();
        if ($user_info) {
            $user_info['avatar'] = $user_info['avatar'] ? doAvatar($user_info['avatar']) : '/images/avatar.png';

            apiReturn(1, '获取用户信息成功', $user_info);
        } else {
            apiReturn(2, '获取用户信息失败');
        }
    }

    /**
     * 获取openid
     */
    public function getOpenid()
    {
        $input = Request()->param();

        $code = $input['code'];

        if (empty($code)) apiReturn(2, '系统繁忙，请稍后再试~');

        $appid = C('XCX_APPID');
        $secret = C('XCX_SECRET');
        $grant_type = 'authorization_code';
        $url = 'https://api.weixin.qq.com/sns/jscode2session?';

        $param = [
            'appid' => $appid,
            'secret' => $secret,
            'js_code' => $code,
            'grant_type' => $grant_type
        ];
        $param_str = http_build_query($param);
        $url .= $param_str;
        $json_res = httpsRequest($url);
        $user_data = json_decode($json_res);

        if ($openid = $user_data->openid) {
            apiReturn(1, '获取数据成功', $openid);
        } else {
            apiReturn(2, '系统繁忙，请稍后再试~');
        }
    }

    /**
     * 获取手机号
     * */
    public function getMobile()
    {
        $input = Request()->param();

        $code = $input['code'];

        if (empty($code) || $code == 'undefined') apiReturn(2, 'code缺失');

        $token = getAccessToken();
        if (empty($token)) apiReturn(2, 'TOKEN缺失');

        $url = 'https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=' . $token . '&code=' . $code;

        file_put_contents(RUNTIME_PATH . 'error.json', json_encode($input, JSON_UNESCAPED_UNICODE) . PHP_EOL, FILE_APPEND);

        $data = [
            'code' => $code
        ];
        $result = httpsRequest($url, json_encode($data));
        file_put_contents(RUNTIME_PATH . 'error.json', $result . PHP_EOL . PHP_EOL, FILE_APPEND);
        $result = json_decode($result, true);

        if ($result['errcode'] == 0) {
            $mobile = $result['phone_info']['phoneNumber'];

            if ($mobile) {
                apiReturn(1, '获取数据成功', $mobile);
            } else {
                apiReturn(2, '系统繁忙，请稍后再试');
            }
        } else {
            if ($result['errcode'] == 40001) {
                apiReturn(2, '系统繁忙，请重新获取手机号');
            } elseif ($result['errcode'] == 40029) {
                apiReturn(3, '获取手机号失败，请前往【我 => 设置 => 关于微信】将微信版本更新至不低于8.0.16后，再回到此界面点击绑定手机');
            } else {
                apiReturn(2, '系统繁忙，请稍后再试~');
            }
        }
    }

    /**
     * 登录
     * */
    public function login()
    {
        $input = Request()->param();

        $openid = $input['openid'];
        $avatar = $input['avatar'];
        $nickname = $input['nickname'];
        $mobile = $input['mobile'];

        if (empty($openid)) apiReturn(2, 'openid缺失');
        if (empty($avatar)) apiReturn(2, '请上传头像信息');
        if (empty($nickname)) apiReturn(2, '请填写昵称');
        if (empty($mobile)) apiReturn(2, '请获取手机号');

        $mobile_count = Db::name('user')->where(['mobile' => $mobile])->count();
        if ($mobile_count > 0) apiReturn(2, '该手机号已使用');

        Db::startTrans();
        try {
            $count = Db::name('user')->where(['openid' => $openid])->count();
            if ($count == 0) {
                $data = [
                    'openid' => $openid,
                    'avatar' => str_replace(getHost(), '', $avatar),
                    'username' => $nickname,
                    'user_type' => 1,
                    'mobile' => $mobile,
                    'end_clock_date' => getDayDate(3),
                    'create_time' => time()
                ];

                $insert_user_id = Db::name('user')->insertGetId($data);
                if (!$insert_user_id) {
                    Db::rollback();
                    apiReturn(2, '系统繁忙，请稍后再试~');
                }
            }

            Db::commit();

            $token = JwtHelper::createToken(['openid' => $openid]);
            apiReturn(1, '登录成功', $token);
        } catch (\Exception $e) {
            Db::rollback();
            apiReturn(2, '系统繁忙，请稍后再试~');
        }
    }

    public function bindUser()
    {
        $openid = self::authorizationGetOpenid();
        if (empty($openid)) apiReturn(401, '您还未登录，请先登录');

        $user_id = openidGetUserId($openid);
        if (empty($user_id)) apiReturn(401, '您还未登录，请先登录');

        $user_info = Db::name('user')->where(['id' => $user_id])->find();
        if (empty($user_info)) apiReturn(2, '用户不存在');

        $input = Request()->param();

        $share_user_id = $input['share_user_id'];

        $share_user_info = Db::name('user')->where(['id' => $share_user_id])->find();
        if (empty($share_user_info)) apiReturn(2, '分享人不存在');

        if (!$share_user_id) apiReturn(2, '参数缺失');

        if ($user_info['up_shop_user_id'] == 0) {
            $data = [
                'up_shop_user_id' => $share_user_id,
                'up_channel_user_id' => $share_user_info['up_channel_user_id'],
                'up_company_user_id' => $share_user_info['up_company_user_id'],
                'update_time' => time()
            ];
            $res = Db::name('user')->where(['id' => $user_id])->update($data);
            if ($res) {
                apiReturn(1, '绑定成功');
            } else {
                apiReturn(2, '绑定失败');
            }
        } else {
            apiReturn(2, '已绑定');
        }


    }

    /**
     * 获取token
     * */
    public function getLoginToken()
    {
        $input = Request()->param();

        $code = $input['code'];

        if (empty($code)) apiReturn(2, '系统繁忙，请稍后再试~');

        $appid = C('XCX_APPID');
        $secret = C('XCX_SECRET');
        $grant_type = 'authorization_code';
        $url = 'https://api.weixin.qq.com/sns/jscode2session?';

        $param = [
            'appid' => $appid,
            'secret' => $secret,
            'js_code' => $code,
            'grant_type' => $grant_type
        ];
        $param_str = http_build_query($param);
        $url .= $param_str;

        $user_data = json_decode(httpsRequest($url));

        if ($user_data->errcode) apiReturn(2, '系统繁忙，请稍后再试~');

        $openid = $user_data->openid;

        if (empty($openid)) apiReturn(2, '登录失败');

        $user_info = Db::name('user')->where('openid', $openid)->find();
        if ($user_info) {
            $token = JwtHelper::createToken(['openid' => $openid]);
            apiReturn(1, '登录成功', $token);
        } else {
            apiReturn(2, '新用户，走注册流程');
        }
    }

    /**
     * 个人中心
     * */
    public function userCenter()
    {
        $openid = self::authorizationGetOpenid();
        if (empty($openid)) apiReturn(401, '您还未登录，请先登录');

        $info = Db::name('user')->field('id,username,avatar,mobile,clock_status')->where(['openid' => $openid])->find();

        $info['avatar'] = $info['avatar'] ? getHost() . $info['avatar'] : '/static/images/avatar.png';
        $info['hide_mobile'] = $info['mobile'] ? hideMobile($info['mobile']) : '';

        apiReturn(1, '获取数据成功', $info);
    }

    /**
     * 获取打卡规则
     * */
    public function getClockRules()
    {
        $clock_time = C('CLOCK_TIME');
        $clock_speed = C('CLOCK_SPEED');
        $clock_price = C('CLOCK_PRICE');
        $clock_video_count = C('CLOCK_VIDEO_COUNT');
        $clock_img_count = C('CLOCK_IMG_COUNT');
        $clock_end_time = C('CLOCK_END_TIME');
        $clock_examine_time = C('CLOCK_EXAMINE_TIME');

        $data = [
            'clock_time' => $clock_time,
            'clock_speed' => $clock_speed,
            'clock_price' => $clock_price,
            'clock_video_count' => $clock_video_count,
            'clock_img_count' => $clock_img_count,
            'clock_end_time' => $clock_end_time,
            'clock_examine_time' => $clock_examine_time,
        ];

        apiReturn(1, '获取数据成功', $data);
    }

    /**
     * 用户打卡
     * */
    public function userClock()
    {
        $openid = self::authorizationGetOpenid();
        if (empty($openid)) apiReturn(401, '您还未登录，请先登录');

        $user_id = openidGetUserId($openid);
        if (empty($user_id)) apiReturn(401, '您还未登录，请先登录');

        $input = Request()->param();

        $day = $input['day'];
        $form_imgs = $input['form_imgs'] ? json_decode($input['form_imgs'], true) : [];
        $form_videos = $input['form_videos'] ? json_decode($input['form_videos'], true) : [];

        if (empty($day)) apiReturn(2, '打卡天数参数缺失');

        $clock_video_count = C('CLOCK_VIDEO_COUNT');
        $clock_img_count = C('CLOCK_IMG_COUNT');
        if (count($form_videos) != $clock_video_count) apiReturn(2, '打卡视频数量不正确');
        if (count($form_imgs) != $clock_img_count) apiReturn(2, '打卡图片数量不正确');

        $imgs_json = array_column($form_imgs, 'path');
        $imgs_text_json = array_column($form_imgs, 'text');
        $video_json = array_column($form_videos, 'path');
        $time = time();

        //        if (hasEmptyItem($imgs_text_json)) apiReturn(2, '请完善图片描述');

        Db::startTrans();
        try {
            $user_clock_info = Db::name('user_clock')->where(['user_id' => $user_id, 'day' => $day])->find();
            if ($user_clock_info) {
                $data = [
                    'imgs_json' => $imgs_json ? json_encode($imgs_json, JSON_UNESCAPED_UNICODE) : '',
                    'imgs_text_json' => $imgs_text_json ? json_encode($imgs_text_json, JSON_UNESCAPED_UNICODE) : '',
                    'video_json' => $video_json ? json_encode($video_json, JSON_UNESCAPED_UNICODE) : '',
                    'is_over' => $user_clock_info['ck_date'] < date('Y-m-d') ? 1 : 0,
                    'status' => 1,
                    'ck_time' => $time,
                    'update_time' => $time,
                ];

                $res = Db::name('user_clock')->where(['user_id' => $user_id, 'day' => $day])->update($data);
                if (!$res) {
                    Db::rollback();
                    apiReturn(2, '打卡失败');
                }
            } else {
                $clock_data = [];
                $date = date('Y-m-d');
                for ($i = 1; $i <= 18; $i++) {
                    if ($day == $i) {
                        $imgs_json = json_encode($imgs_json, JSON_UNESCAPED_UNICODE);
                        $imgs_text_json = json_encode($imgs_text_json, JSON_UNESCAPED_UNICODE);
                        $video_json = json_encode($video_json, JSON_UNESCAPED_UNICODE);
                        $status = 1;
                        $ck_time = $time;
                        $update_time = $time;

                    } else {
                        $imgs_json = '';
                        $imgs_text_json = '';
                        $video_json = '';
                        $status = 0;
                        $ck_time = 0;
                        $update_time = 0;
                    }

                    $clock_data[] = [
                        'user_id' => $user_id,
                        'day' => $i,
                        'imgs_json' => $imgs_json,
                        'imgs_text_json' => $imgs_text_json,
                        'video_json' => $video_json,
                        'status' => $status,
                        'ck_date' => getDayDate($i - 1, $date),
                        'ck_time' => $ck_time,
                        'update_time' => $update_time,
                    ];
                }
                $res = Db::name('user_clock')->insertAll($clock_data);
                if (!$res) {
                    Db::rollback();
                    apiReturn(2, '打卡失败');
                }

                $res = Db::name('user')->where('id', $user_id)->update(['clock_status' => 2, 'update_time' => $time]);
                if (!$res) {
                    Db::rollback();
                    apiReturn(2, '打卡失败');
                }
            }

            Db::commit();
            apiReturn(1, '打卡成功');
        } catch (\Exception $e) {
            Db::rollback();
            apiReturn(2, '打卡失败' . $e->getMessage());
        }
    }

    /**
     * 用户打卡记录
     * */
    public function userClockRecord()
    {
        $openid = self::authorizationGetOpenid();
        if (empty($openid)) apiReturn(401, '您还未登录，请先登录');

        $user_id = openidGetUserId($openid);
        if (empty($user_id)) apiReturn(401, '您还未登录，请先登录');

        $is_vip = Db::name('user')->where('id', $user_id)->value('is_vip');

        $list = Db::name('user_clock')->field('id,day,ck_date,status')->where(['user_id' => $user_id])->order('day asc')->select();
        $day = 1;// 今天是第几天打卡
        foreach ($list as &$v) {
            $is_today = 0;
            if ($v['ck_date'] == date('Y-m-d')) {
                $is_today = 1;
                $day = $v['day'];
            }

            $v['is_today'] = $is_today;
        }

        $user_max_ck_date = Db::name('user_clock')->where(['user_id' => $user_id])->order('ck_date desc')->value('ck_date');

        $data = [
            'day' => $day,
            'is_vip' => $is_vip,
            'list' => $list,
            'is_complete' => $user_max_ck_date < date('Y-m-d') ? 1 : 0,
        ];
        apiReturn(1, '获取数据成功', $data);
    }

    /**
     * 获取用户打卡信息
     * */
    public function getUserClockInfo()
    {
        $openid = self::authorizationGetOpenid();
        if (empty($openid)) apiReturn(401, '您还未登录，请先登录');

        $user_id = openidGetUserId($openid);
        if (empty($user_id)) apiReturn(401, '您还未登录，请先登录');

        $input = Request()->param();

        $day = $input['day'] ? : 1;

        $info = Db::name('user_clock')->where(['user_id' => $user_id, 'day' => $day])->find();

        $video_json = $info['video_json'] ? json_decode($info['video_json'], true) : [];
        if ($video_json) {
            $form_videos = [];
            foreach ($video_json as $v) {
                $form_videos[] = [
                    'path' => $v,
                    'is_play' => false
                ];
            }
        }

        $imgs_json = $info['imgs_json'] ? json_decode($info['imgs_json'], true) : [];
        if ($imgs_json) {
            $imgs_text_json = $info['imgs_text_json'] ? json_decode($info['imgs_text_json'], true) : [];

            $form_imgs = [];
            foreach ($imgs_json as $k => $v) {
                $form_imgs[] = [
                    'path' => $v,
                    'text' => $imgs_text_json[$k]
                ];
            }
        }

        $data = [
            'info' => $info,
            'form_videos' => $form_videos,
            'form_imgs' => $form_imgs
        ];

        apiReturn(1, '获取数据成功', $data);
    }

    /**
     * 未读消息数量
     * */
    public function msgCount()
    {
        $openid = self::authorizationGetOpenid();
        if (empty($openid)) apiReturn(401, '您还未登录，请先登录');

        $user_id = openidGetUserId($openid);
        if (empty($user_id)) apiReturn(401, '您还未登录，请先登录');

        $count = Db::name('msg')->where(['user_id' => $user_id, 'is_read' => 0, 'is_show' => 1])->count();

        apiReturn(1, '获取数据成功', $count);
    }

    /**
     * 消息列表
     * */
    public function msgList()
    {
        $openid = self::authorizationGetOpenid();
        if (empty($openid)) apiReturn(401, '您还未登录，请先登录');

        $user_id = openidGetUserId($openid);
        if (empty($user_id)) apiReturn(401, '您还未登录，请先登录');

        $input = Request()->param();

        $page = $input['page'] ? : 1;
        $pagesize = $input['pagesize'] ? : 10;

        $list = Db::name('msg')->where(['user_id' => $user_id, 'is_show' => 1])->order('id desc')->page($page, $pagesize)->select();
        if ($list) {
            foreach ($list as &$v) {
                $v['create_time'] = date('Y-m-d H:i', $v['create_time']);

                if ($v['type'] == 'transfer_pay_money') {
                    $package_info = Db::name('user_clock')->where(['user_id' => $user_id, 'day' => $v['day'], 'pay_status' => 1])->value('package_info');
                    $mch_id = C('MCH_ID');
                } else {
                    $package_info = '';
                }
                $v['package_info'] = $package_info;
                $v['mch_id'] = $mch_id;
            }
            apiReturn(1, '获取数据成功', $list);
        } else {
            apiReturn(2, '暂无更多数据');
        }
    }

    /**
     * 消息已读
     * */
    public function msgRead()
    {
        $openid = self::authorizationGetOpenid();
        if (empty($openid)) apiReturn(401, '您还未登录，请先登录');

        $user_id = openidGetUserId($openid);
        if (empty($user_id)) apiReturn(401, '您还未登录，请先登录');

        Db::name('msg')->where(['user_id' => $user_id, 'is_read' => 0])->setField('is_read', 1);

        apiReturn(1, '已读成功');
    }

    /**
     * 获取付款凭证
     * */
    public function getPayVoucher()
    {
        $openid = self::authorizationGetOpenid();
        if (empty($openid)) apiReturn(401, '您还未登录，请先登录');

        $user_id = openidGetUserId($openid);
        if (empty($user_id)) apiReturn(401, '您还未登录，请先登录');

        $input = Request()->param();

        $day = $input['day'];
        if (empty($day)) apiReturn(2, '打卡天数缺失');

        $info = Db::name('user_clock')->where(['user_id' => $user_id, 'day' => $day])->find();
        if ($info) {
            $info['img'] = getHost() . $info['img'];
            apiReturn(1, '获取数据成功', $info);
        } else {
            apiReturn(2, '打卡数据不存在');
        }
    }

    /**
     * 文章详情
     * */
    public function articleDetail()
    {
        $input = Request()->param();

        $id = $input['id'];

        if (empty($id)) apiReturn(2, '文章ID缺失');

        $info = Db::name('article')->where(['id' => $id])->find();
        if ($info) {
            if ($info['show_type'] == 1) {
                $info['content'] = doEditorContent($info['content']);
            } else {
                $info['video'] = getHost() . $info['video'];
            }
            $info['create_time'] = timeFormat($info['create_time']);

            apiReturn(1, '获取数据成功', $info);
        } else {
            apiReturn(2, '文章不存在或已删除');
        }
    }

    /**
     * 收款账户页面获取规则
     * */
    public function getAccountRule()
    {
        $rule = explode(PHP_EOL, C('WITHDRAWAL_RULE'));
        apiReturn(1, '获取数据成功', $rule);
    }

    /**
     * 保存账户信息
     * */
    public function saveAccount()
    {
        $openid = self::authorizationGetOpenid();
        if (empty($openid)) apiReturn(401, '您还未登录，请先登录');

        $user_id = openidGetUserId($openid);
        if (empty($user_id)) apiReturn(401, '您还未登录，请先登录');

        $input = Request()->param();

        $account_type = $input['account_type'];
        $alipay_name = $input['alipay_name'] ? : '';
        $alipay_mobile = $input['alipay_mobile'] ? : '';
        $bank_user = $input['bank_user'] ? : '';
        $bank_num = $input['bank_num'] ? : '';
        $bank_name = $input['bank_name'] ? : '';

        if (empty($account_type)) apiReturn(2, '请选择账户类型');
        if ($account_type == 1 && (empty($alipay_name) || empty($alipay_mobile))) apiReturn(2, '请完善支付宝信息');
        if ($account_type == 2 && (empty($bank_user) || empty($bank_num) || empty($bank_name))) apiReturn(2, '请完善银行卡信息');

        $data = [
            'account_type' => $account_type,
            'alipay_name' => $alipay_name,
            'alipay_mobile' => $alipay_mobile,
            'bank_user' => $bank_user,
            'bank_num' => $bank_num,
            'bank_name' => $bank_name,
            'update_time' => time()
        ];

        $res = Db::name('user')->where('id', $user_id)->update($data);
        if ($res) {
            apiReturn(1, '保存成功');
        } else {
            apiReturn(2, '保存失败');
        }
    }

    /**
     * 获取账户信息
     * */
    public function getAccount()
    {
        $openid = self::authorizationGetOpenid();
        if (empty($openid)) apiReturn(401, '您还未登录，请先登录');

        $user_id = openidGetUserId($openid);
        if (empty($user_id)) apiReturn(401, '您还未登录，请先登录');

        $info = Db::name('user')->where('id', $user_id)->find();
        apiReturn(1, '获取数据成功', $info);
    }

    /**
     * 检查用户是否还有待收款的数据
     * */
    public function checkUserClock()
    {
        $openid = self::authorizationGetOpenid();
        if (empty($openid)) apiReturn(401, '您还未登录，请先登录');

        $user_id = openidGetUserId($openid);
        if (empty($user_id)) apiReturn(401, '您还未登录，请先登录');

        $package_info = Db::name('user_clock')->where(['user_id' => $user_id, 'status' => 2, 'pay_status' => 1])->value('package_info');

        if ($package_info) {
            if ($mch_id = C('MCH_ID')) {
                $data = [
                    'package_info' => $package_info,
                    'mch_id' => $mch_id,
                ];
                apiReturn(1, '获取数据成功', $data);
            } else {
                apiReturn(2, '请配置商户号');
            }
        } else {
            apiReturn(2, '没有待收款的数据');
        }
    }

    public function getVirtualData()
    {
        $user = Db::name('virtual')->where('id', 1)->value('data');
        $color = Db::name('virtual')->where('id', 2)->value('data');
        $is_open = Db::name('virtual')->where('id', 3)->value('data');

        $user = json_decode($user, true);
        $color = explode(',', $color);

        $data = [
            'user' => $user,
            'color' => $color,
            'is_open' => $is_open
        ];

        apiReturn(1, '获取数据成功', $data);
    }
}
